﻿using System;

namespace com.susi.util.toolkit
{
    /// <summary>
    /// 对字段进行一层包装，以获得其变更事件
    /// <br>另相似的.net方案参见</br>
    /// <br><see cref="System.ComponentModel.INotifyPropertyChanged"/></br>
    /// <br>【官方文档】https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged?view=net-5.0 </br>
    /// <br>【INotifyPropertyChanged 接口的优雅用法：Fody】https://www.jianshu.com/p/40cf8c68198b </br>
    /// <br>PM> Install-Package PropertyChanged.Fody</br>
    /// </summary>
    public struct EventValue<T> : IDisposable
    {
        public EventValue(T v)
        {
            this.v = v;
            onChangedEvent = null;
            onDisposeEvent = null;
        }

        public T v;
        public event Action onDisposeEvent;
        public event Action onChangedEvent;

        public void Change(T v)
        {
            this.v = v;
            onChangedEvent?.Invoke();
        }
        public void Touch()
        {
            onChangedEvent?.Invoke();
        }
        public void Dispose()
        {
            onDisposeEvent?.Invoke();
            if (v is IDisposable dis) dis.Dispose();
            v = default;
            onChangedEvent = null;
            onDisposeEvent = null;
        }

        public static implicit operator T(EventValue<T> v)
        {
            return v.v;
        }
    }
}
